

let deviceList = [],// 设备列表
	bluetooth_switch = false,//蓝牙连接状态
	select_device = {},//选择的设备列表//createBLEConnection
	connection = false,//连接设备控制，让其只触发一次
	timer = null,//定时器
	device_server = [],//设备服务//getBLEDeviceServices
	device_server_bottom = 0,//设备服务的下标
	characteristics = [],//某个设备服务下的所有特征值//getBLEDeviceCharacteristics
	characteristics_bottom = 0//某个设备服务特征值下标


// 封装的一个弹窗
// 封装弹窗
// 封装的消息弹窗
function toast(title) {
	uni.showToast({
		title,
		icon: "none"
	})
}

export default {
	bluetooth_switch,//蓝牙连接状态
	// 初始化蓝牙
	initialize() {
		//在页面加载时候初始化蓝牙适配器
		uni.openBluetoothAdapter({
			success: res => {
				toast("初始化蓝牙成功")
				console.log('初始化蓝牙成功:' + res.errMsg)
				// 初始化完毕开始搜索
				this.startBluetoothDeviceDiscovery()
			},
			fail: err => {
				console.log('初始化失败initialize');
				console.log('初始化蓝牙失败，错误码：' + (err.errCode || err.errMsg));
				if (err.errCode == 10001) {
					// toast("请打开蓝牙并重试")
					uni.showModal({
						content: "请打开蓝牙服务并重试"
					})
					return
				}
				toast("初始化失败,请重试")
			}
		})
	},
	// 搜索蓝牙
	startBluetoothDeviceDiscovery() {
		uni.startBluetoothDevicesDiscovery({
			success: e => {
				// 显示弹窗
				uni.showLoading({
					title: "设备搜索中",
					mask: true
				})
				// 
				console.log('开始搜索蓝牙设备:' + e.errMsg)
				// 监听新设备
				this.onBluetoothDeviceFound()
			},
			fail: e => {
				uni.showModal({
					title: "设备搜索失败",
					content: "请打开位置服务和蓝牙"
				})
				console.log('搜索蓝牙设备失败，错误码：' + e.errCode)
			}
		})
		//30秒结束蓝牙搜索
		timer = setTimeout(() => {
			// 结束蓝牙搜索
			this.endBluetoothDeviceDiscovery()
		}, 30000)

	},
	// 结束蓝牙搜索
	endBluetoothDeviceDiscovery() {
		uni.stopBluetoothDevicesDiscovery()
		// 隐藏弹窗
		uni.hideLoading()
	},
	// 监听新设备
	onBluetoothDeviceFound() {
		uni.onBluetoothDeviceFound(res => {
			console.log(res, "新设备列表")
			// 获取已发现的设备
			this.getBluetoothDevices()
		})
	},
	// 获取已发现的设备
	getBluetoothDevices() {
		uni.getBluetoothDevices({
			success: res => {
				console.log('获取蓝牙设备成功:' + res.errMsg)
				// 设备列表
				deviceList = res.devices
				// 选择设备
				this.queryDevices()
			},
			fail: e => {
				console.log('获取蓝牙设备错误，错误码：' + e)
			}
		})
	},
	// 选择设备
	queryDevices() {
		for (let i in deviceList) {
			if (connection) break
			console.log(deviceList[i], "name：" + deviceList[i].name, "localName：" + deviceList[i].localName)
			// 判断name || localName 是否存在
			if (!deviceList[i].name || !deviceList[i].localName) continue
			// 设备名称判断
			if (deviceList[i].name.includes("调香馆") ||
				deviceList[i].name.includes("卡杰香氛A8") ||
				deviceList[i].name.includes("调香馆中国-4F") ||
				deviceList[i].localName.includes("调香馆") ||
				deviceList[i].localName.includes("卡杰香氛A8") ||
				deviceList[i].localName.includes("调香馆中国-4F")) {
				// 获取选择的设备
				select_device = deviceList[i]
				// 清除定时器
				if (timer) clearTimeout(timer)
				// 修改选择创建连接次数 为true 则后面不在进行渲染
				connection = true
				// 设置30秒后恢复为false
				setTimeout(() => connection = false, 30000)
				// 结束蓝牙搜索
				this.endBluetoothDeviceDiscovery()
				// 创建蓝牙连接
				this.createBLEConnection()
				// 结束循环
				break
			}
		}
	},
	// 创建蓝牙连接
	createBLEConnection() {
		// 判断蓝牙是否连接
		if (bluetooth_switch) return
		// 获取选择的设备的设备id
		let deviceId = select_device.deviceId
		// 弹窗
		uni.showLoading({
			title: "连接蓝牙中..."
		})
		// 创建蓝牙连接
		uni.createBLEConnection({
			deviceId,
			success: res => {
				// 修改连接状态
				bluetooth_switch = true
				// 
				console.log('连接蓝牙成功:' + JSON.stringify(res))
				uni.hideLoading()
				uni.hideToast()
				// 显示通知弹窗
				toast("连接成功")
				// 监听蓝牙的状态
				this.onBLEConnectionStateChange()
				// 获取设备的所有服务
				this.getBLEDeviceServices()
			},
			fail: e => {
				// 修改连接状态
				bluetooth_switch = false
				// 
				console.log('连接低功耗蓝牙失败，错误码：' + e.errCode)
				uni.hideLoading()
				// 显示通知弹窗
				toast("连接失败,请重试")
			}
		})
	},
	// 
	// 获取设备的所有服务
	getBLEDeviceServices() {
		let deviceId = select_device.deviceId

		uni.getBLEDeviceServices({
			// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
			deviceId,
			success: res => {
				if (!res.services.length) {
					toast('获取服务失败，请重试!')
					return
				}
				// 设备所有服务
				device_server = res.services
				//获取某个服务下的所有特征值
				this.getBLEDeviceCharacteristics()
				// 
				console.log(device_server, "所有特征值服务")
			},
			fail: e => {
				console.log('获取设备服务失败，错误码：' + e.errCode)
			}
		});
	},
	//获取某个服务下的所有特征值
	getBLEDeviceCharacteristics() {
		let deviceId = select_device.deviceId,
			serviceId = device_server[device_server_bottom].uuid

		uni.getBLEDeviceCharacteristics({
			// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
			deviceId,
			// 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
			serviceId,
			success: res => {
				if (!res.characteristics.length) {
					toast('获取特征值失败，请重试!')
					return
				}
				// 获取某个服务所有的设备服务特征值
				characteristics = res.characteristics
				// 
				console.log('获取特征值成功:', res)
				// 
				// 读取设备当前工作状态
				this.read_device_status()
				//开启订阅服务，监听设备服务订阅值的变化
				this.notifyBLECharacteristicValueChange()

				// 
				// 判断运行时间和间隔时间是否设有初始值、没有则进行手动初始化
				if (!uni.getStorageSync("run_time") || !uni.getStorageSync("interval_time")) this.bluetooth_work_time(30, 300)
				// 发送当前时间以设置蓝牙当前时间
				this.send_new_time()
			},
			fail: e => console.log('获取特征值失败，错误码：' + e.errCode)
		})
	},
	// 读取设备当前工作状态
	read_device_status() {
		// 读取设备当前工作状态
		uni.readBLECharacteristicValue({
			// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
			deviceId: select_device.deviceId,
			// 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
			serviceId: device_server[device_server_bottom].uuid,
			// 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
			characteristicId: characteristics[characteristics_bottom].uuid,
			success: (res) => {
				console.log("我当前工作状态为:", res)
			}, fail: (err) => {
				console.log("我当前工作状态为:", err)
			}
		})
	},
	// 发送当前时间以设置蓝牙当前时间
	send_new_time() {
		// 获取时间
		let date = new Date(),
			year = this.system_conversion(String(date.getFullYear()).split("0")[1]),//年
			month = this.system_conversion(date.getMonth() + 1),//月
			day = this.system_conversion(date.getDate()),//日
			hours = this.system_conversion(date.getHours()),// 时
			minuties = this.system_conversion(date.getMinutes()),// 分
			seconds = this.system_conversion(date.getSeconds()),// 秒
			weeks = this.system_conversion(date.getDay()),// 星期几
			// 设置需要写入的数据
			value = this.stringToHexBuffer(`50 ${year[0]} ${month[0]} ${day[0]} ${hours[0]} ${minuties[0]} ${seconds[0]} ${weeks[0]} 00 00 00`)
		// 
		// 打印需要写入的数据
		console.log("我是需要写入的数据", value)
		// 写入数据
		wx.writeBLECharacteristicValue({
			deviceId: select_device.deviceId,
			serviceId: device_server[device_server_bottom].uuid,
			characteristicId: characteristics[characteristics_bottom].uuid,
			value,
			success: (res) => {
				// toast("设置成功")
				console.log("重置当前时间-写入成功:", res)
			},
			fail: (err) => {
				// toast("设置失败 请重试")
				console.log("重置当前时间-写入失败:", err)
			}
		})
	},
	// 
	// 
	//页面操作
	// 
	// 页面操作-判断蓝牙是否连接
	bluetooth_switch() {
		return new Promise((resolve, reject) => {
			if (bluetooth_switch) {
				resolve({
					code: 0,
					msg: "蓝牙已连接"
				})
			} else {
				reject({
					code: -1,
					msg: "蓝牙未连接"
				})
			}
		})
	},
	// 页面操作-打开机器开始工作
	bluetooth_open() {
		return new Promise((resolve, reject) => {
			// 进制转换
			let value = this.stringToHexBuffer("59 55 55 55 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00")
			console.log("我是打开机器的值", value)
			// 写入数据
			wx.writeBLECharacteristicValue({
				deviceId: select_device.deviceId,
				serviceId: device_server[device_server_bottom].uuid,
				characteristicId: characteristics[characteristics_bottom].uuid,
				value,
				success: (res) => {
					toast("已打开")
					console.log("写入成功toWorking:", res)
					resolve(res)
				},
				fail: (err) => {
					toast("设备开启失败 请重试")
					console.log("写入失败:", err)
				}
			})
		})
	},
	// 页面操作-关闭机器
	bluetooth_close() {
		return new Promise((resolve, reject) => {
			// 进制转换
			let value = this.stringToHexBuffer("59 55 55 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00")
			// 
			console.log("我是关闭机器的值", value)
			// 写入数据
			wx.writeBLECharacteristicValue({
				deviceId: select_device.deviceId,
				serviceId: device_server[device_server_bottom].uuid,
				characteristicId: characteristics[characteristics_bottom].uuid,
				value,
				success: (res) => {
					toast("已关闭")
					console.log("写入成功stopWorking:", res)
					resolve(res)
				},
				fail: (err) => {
					toast("设备关闭失败 请重试")
					console.log("写入失败:", err)
				}
			})
		})
	},
	// 设置工作运行时间和间隔时间
	bluetooth_work_time(runTime, intervalTime) {
		let run_time = this.system_conversion(runTime),//运行时间
			interval_time = this.system_conversion(intervalTime)//间隔时间
		return new Promise((resolve, reject) => {
			// 进制转换
			let value = this.stringToHexBuffer(`52 00 00 00 23 59 ${run_time[1] ? run_time[0] : '00'} ${run_time[1] ? run_time[1] : run_time[0]} ${interval_time[1] ? interval_time[0] : '00'} ${interval_time[1] ? interval_time[1] : interval_time[0]} 7F`)
			console.log("我是设置工作和运行时间", value)
			// 写入数据
			wx.writeBLECharacteristicValue({
				deviceId: select_device.deviceId,
				serviceId: device_server[device_server_bottom].uuid,
				characteristicId: characteristics[characteristics_bottom].uuid,
				value,
				success: (res) => {
					toast("设置成功")
					console.log("运行时间和间隔时间-写入成功:", res)
					resolve(res)
				},
				fail: (err) => {
					toast("设置失败 请重试")
					console.log("运行时间和间隔时间-写入失败:", err)
				}
			})

		})
	},
	// 设置香氛浓度模式
	bluetooth_model(opt) {
		return new Promise((resolve, reject) => {
			// 模式判断
			let model = opt == 0 ? 1 : opt == 1 ? 2 : opt == 2 ? 3 : opt == 3 ? 4 : 1
			// 进制转换
			let value = this.stringToHexBuffer(`5C 0${model} 00 00 00 00 00 00 00 00 00`)
			// 我是设置浓度模式前的数据
			console.log("我是设置浓度模式的数据", value)
			// 写入数据
			wx.writeBLECharacteristicValue({
				deviceId: select_device.deviceId,
				serviceId: device_server[device_server_bottom].uuid,
				characteristicId: characteristics[characteristics_bottom].uuid,
				value,
				success: (res) => {
					// toast(model == 1 ? "已切换,当前浓度为: 淡" : model == 2 ? "已切换,当前浓度为: 弱" : model == 3 ? "已切换,当前浓度为: 中" : model == 4 ? "已切换,当前浓度为: 强" : "已切换,当前浓度为: 淡")
					// console.log("模式切换成功-当前模式为:" + model,"1淡 2弱 3中 4强", res)
					resolve(1)
				},
				fail: (err) => {
					toast("浓度模式修改失败")
					// console.log("模式切换失败-当前模式为:" + model,"1淡 2弱 3中 4强", err)
				}
			})
		})
	},
	// 
	// 







	// 
	// 
	//订阅操作成功后需要设备主动更新特征值的 value，才会触发 uni.onBLECharacteristicValueChange 回调
	notifyBLECharacteristicValueChange() {
		let deviceId = select_device.deviceId,
			serviceId = device_server[device_server_bottom].uuid,
			characteristicId = characteristics[characteristics_bottom].uuid
		// 
		uni.notifyBLECharacteristicValueChange({
			state: true, // 启用 notify 功能
			// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
			deviceId,
			// 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
			serviceId,
			// 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
			characteristicId,
			success: (res) => console.log(res, "订阅值"),
			fail: err => console.log(err, "订阅值-失败")
		})
	},
	//监听低功耗蓝牙连接状态的改变事件。包括开发者主动连接或断开连接，设备丢失，连接异常断开等等
	onBLEConnectionStateChange() {
		uni.onBLEConnectionStateChange(res => {
			// 该方法回调中可以用于处理连接意外断开等异常情况
			console.log(res, "蓝牙监听状态");
			if (!res.connected) {
				// 修改连接状态
				bluetooth_switch = false

				toast('已经断开当前蓝牙连接');
			}
		})
	},
	// 断开连接并释放资源
	disconnect() {
		// 获取选择的设备的设备id
		let deviceId = select_device.deviceId
		uni.closeBLEConnection({
			deviceId,
			complete: (res) => {
				console.log(res)
			}
		})
		// uni.closeBLEConnection({
		// 	deviceId
		// })
	},
	// 

	// 
	// 
	// 数值 10进制转16进制
	system_conversion(e) {
		let value = null, result = [], num = parseInt(e)
		// 从10进制转16进制，并转换大写
		value = num.toString(16).toUpperCase()
		// 打印出转换后的进制值
		console.log("我是转换后的值", value)
		// 判断是否为2位,不存在则在前补零
		if (value.length == 1) value = 0 + value
		// 判断是否为4位，不存在则在前补零
		else if (value.length == 3) value = 0 + value
		// 打印补零后的值
		console.log("我是补零后的值", value)
		// 每两位添加空格
		for (let i = 0; i < value.length; i++) result.push(value.slice(2 * i, 2 * (i + 1)))
		// 打印转换完成后的数据
		console.log("我是10转16完成后的数据", result)
		// 输出
		return result
	},
	// Buffer 16进制转换
	stringToHexBuffer(e) {
		return console.log("buffer", e), new Uint8Array(e.match(/[\da-f]{2}/gi).map(function (e) {
			return parseInt(e, 16);
		})).buffer;
	},
	// 
}
